package controllers;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import dao.QuestionDAORemote;
import dto.QuestionValidDTO;

@ManagedBean(name = "qController")
@SessionScoped
public class QuestionValidDTOController {

	@EJB
	QuestionDAORemote qBean;

	List<QuestionValidDTO> allQuestions = new ArrayList<QuestionValidDTO>();
	private ArrayList<String> checkboxValid = new ArrayList<String>();
	private HtmlDataTable dataTable;
	private int catID;
	private int currentCategoryId;
	private String messageClass;
	private UIComponent deleteButton;
	private UIComponent validateButton;
	String buttonFirstPrev;
	String buttonNextLast;
	String buttonValidate;

	@PostConstruct
	public void setCurrentCID() {
		currentCategoryId = -1;
	}

	public String validateQuestion(ActionEvent event) {
		removeDuplicates(checkboxValid);
		for (String s : checkboxValid) {
			qBean.changeQuestionValid(Integer.parseInt(s));
		}
		return "validated";
	}
	
	public String deleteInvalid(QuestionValidDTO qDTO) {
		int d = qBean.removeQuestionFromDatabase(qDTO);
		allQuestions.remove(qDTO);
		if (d == 1) {
			FacesMessage message = new FacesMessage("Question deleted successfully!");
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(deleteButton.getClientId(context), message);
			messageClass = "success";
		} else {
			FacesMessage message = new FacesMessage("An error occured, please try again later!");
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(deleteButton.getClientId(context), message);
			messageClass = "errorMessage";
		}
		return "removed";
	}

	// remove duplicate entries from the checklist
	private static <T> void removeDuplicates(ArrayList<T> list) {
		int size = list.size();
		int out = 0;
		{
			final Set<T> encountered = new HashSet<T>();
			for (int in = 0; in < size; in++) {
				final T t = list.get(in);
				final boolean first = encountered.add(t);
				if (first) {
					list.set(out++, t);
				}
			}
		}
		while (out < size) {
			list.remove(--size);
		}
	}

	// Pagination Actions
	// -----------------------------------------------------------------------------------

	public void pageFirst(ActionEvent event) {
		System.out.println("qController: pageFirst");
		dataTable.setFirst(0);
	}

	public void pagePrevious(ActionEvent event) {
		System.out.println("qController: pagePrevious");
		dataTable.setFirst(dataTable.getFirst() - dataTable.getRows());
	}

	public void pageNext(ActionEvent event) {
		System.out.println("qController: pageNext -- getFirst: " + dataTable.getFirst() + "-- getRows: "
				+ dataTable.getRows());
		dataTable.setFirst(dataTable.getFirst() + dataTable.getRows());
	}

	public void pageLast(ActionEvent event) {
		int count = dataTable.getRowCount();
		int rows = dataTable.getRows();
		System.out.println("qController: pageLast -- count: " + count + "-- rows: " + rows);
		dataTable.setFirst(count - ((count % rows != 0) ? count % rows : rows));
	}

	// Pagination Special getters
	// ---------------------------------------------------------------------------

	public int getCurrentPage() {
		int rows = dataTable.getRows();
		int first = dataTable.getFirst();
		int count = dataTable.getRowCount();
		return (count / rows) - ((count - first) / rows) + 1;
	}

	public int getTotalPages() {
		int rows = dataTable.getRows();
		int count = dataTable.getRowCount();
		return (count / rows) + ((count % rows != 0) ? 1 : 0);
	}

	// Getters and Setters
	// --------------------------------------------------------------------------

	/**
	 * @param qList
	 *            the qList to set
	 */
	public void setallQuestions(List<QuestionValidDTO> allQuestions) {
		this.allQuestions = allQuestions;
	}

	/**
	 * @return the qList
	 */
	public List<QuestionValidDTO> getallQuestions() {
		return allQuestions;
	}

	/**
	 * @return the checkboxValid
	 */
	public ArrayList<String> getcheckboxValid() {
		return checkboxValid;
	}

	/**
	 * @param checkboxValid
	 *            the checkboxValid to set
	 */
	public void setcheckboxValid(ArrayList<String> checkboxValid) {
		this.checkboxValid.addAll(checkboxValid);
	}

	/**
	 * @return the dataTable
	 */
	public HtmlDataTable getDataTable() {
		return dataTable;
	}

	/**
	 * @param dataTable
	 *            the dataTable to set
	 */
	public void setDataTable(HtmlDataTable dataTable) {
		this.dataTable = dataTable;
	}

	/**
	 * @param catID
	 *            the catID to set
	 */
	public void setCatID(int catID) {
		this.catID = catID;
	}

	/**
	 * @return the catID
	 */
	public int getCatID() {
		return catID;
	}

	/**
	 * @param currentCategoryId
	 *            the currentCategoryId to set Get all the questions for the
	 *            selected category.
	 */
	public void setCurrentCategoryId(int currentCategoryId) {
		allQuestions = qBean.getAllQuestionsForValidation(currentCategoryId);
		this.currentCategoryId = currentCategoryId;
	}

	/**
	 * @return the currentCategoryId
	 */
	public int getCurrentCategoryId() {
		return currentCategoryId;
	}

	/**
	 * @param buttonFirstPrev
	 *            the buttonFirstPrev to set
	 */
	public void setbuttonFirstPrev(String buttonFirstPrev) {
		this.buttonFirstPrev = buttonFirstPrev;
	}

	/**
	 * @return the buttonFirstPrev
	 */
	public String getbuttonFirstPrev() {
		if (dataTable.getFirst() == 0) {
			return "buttonDis";
		}
		return "button";
	}

	/**
	 * @return the buttonNextLast
	 */
	public String getButtonNextLast() {
		int rows = dataTable.getRows();
		int first = dataTable.getFirst();
		int count = dataTable.getRowCount();
		int currentPage = (count / rows) - ((count - first) / rows) + 1;
		int totalPages = (count / rows) + ((count % rows != 0) ? 1 : 0);
		if (currentPage == totalPages) {
			return "buttonDis";
		}
		if (allQuestions.isEmpty()) {
			return "buttonDis";
		}
		return "button";
	}

	/**
	 * @param buttonNextLast
	 *            the buttonNextLast to set
	 */
	public void setButtonNextLast(String buttonNextLast) {
		this.buttonNextLast = buttonNextLast;
	}

	/**
	 * @return the buttonValidate
	 */
	public String getButtonValidate() {
		if (allQuestions.isEmpty()) {
			return "buttonDis";
		}
		return "button";
	}

	/**
	 * @param buttonValidate
	 *            the buttonValidate to set
	 */
	public void setButtonValidate(String buttonValidate) {
		this.buttonValidate = buttonValidate;
	}

	/**
	 * @param messageClass
	 *            the messageClass to set
	 */
	public void setMessageClass(String messageClass) {
		this.messageClass = messageClass;
	}

	/**
	 * @return the messageClass
	 */
	public String getMessageClass() {
		return messageClass;
	}

	/**
	 * @param deleteButton
	 *            the deleteButton to set
	 */
	public void setDeleteButton(UIComponent deleteButton) {
		this.deleteButton = deleteButton;
	}

	/**
	 * @return the deleteButton
	 */
	public UIComponent getDeleteButton() {
		return deleteButton;
	}

	/**
	 * @param validateButton
	 *            the validateButton to set
	 */
	public void setValidateButton(UIComponent validateButton) {
		this.validateButton = validateButton;
	}

	/**
	 * @return the validateButton
	 */
	public UIComponent getValidateButton() {
		return validateButton;
	}

}
